home *** CD-ROM | disk | FTP | other *** search
- ; $VER: 1.2 (07.04.01)
- ; COPYRIGHT (C) 2001 RDC SOFTWARE
- ; Distributed under GPL license - see gpl.txt
-
- ; This is a part of ps2m package,
- ; you can obtain latest version at Aminet:
-
- ; ftp://ftp.wustl.edu/pub/aminet/hard/hack/ps2m.lha
- ; ftp://ftp.wustl.edu/pub/aminet/hard/hack/ps2m.readme
-
- ; Use picasm by Timo Rossi to compile.
- ; Amiga version of picasm is included in devpic package:
-
- ; ftp://ftp.wustl.edu/pub/aminet/dev/cross/devpic.lha
- ; ftp://ftp.wustl.edu/pub/aminet/dev/cross/devpic.readme
-
- ; For any questions: rdc@mindless.com
-
- device pic16f876
- include "16f876.i"
- include "macros.i"
-
- WHEEL equ 1
- TOWER equ 1
- SPEED equ 42 ;42 for 4MHz, 52 for 5MHz
-
- ; ---------
- ; variables
- ; ---------
-
- org 0x20
-
- memstart
- count ds 1
- recvb ds 1
- recvc ds 1
- recvd ds 2
- recvdt ds 1
- sendata ds 1
- sendetc ds 1
- intw ds 1
- ints ds 1
- wdtp ds 1
- wdtm ds 2
- temp1 ds 1
- currbyte ds 1
- xdif ds 1
- ydif ds 1
- xdir ds 1
- ydir ds 1
- xspeed ds 2
- yspeed ds 2
- xcount ds 1
- ycount ds 1
- xtemp ds 1
- ytemp ds 1
- flags ds 1
-
- byte1 ds 1
- byte2 ds 1
- byte3 ds 1
- if WHEEL
- byte4 ds 1
- zdif ds 1
- zcount ds 1
- endif
-
- mem_end org 0x000
-
- ; ---------------
- ; bit definitions
- ; ---------------
-
- fpkt1 equ 0
- fpkt2 equ 1
- fpkt3 equ 2
- fbyte equ 3
- fnores equ 4
- fnofps equ 5
-
- if WHEEL
- fwheel equ 6
- endif
-
- if TOWER
- fon equ 7
- endif
-
- ; ----------------
- ; init PIC & mouse
- ; ----------------
-
- start clrf INTCON
- movlw b'10000001'
- option
- goto start_a
-
- ; -----------------
- ; interrupt handler
- ; -----------------
-
- int local
- bcf INTCON,1
- movwf intw
- swapfw STATUS
- movwf ints
- bcf recvd+1,2
- btfsc PORTB,1
- bsf recvd+1,2
- rrf recvd+1
- rrf recvd
- bsf wdtp,5 ;clear packet bit shift watchdog
- loop =a,recvc
- movlf 11,recvc
- bsf flags,fbyte
- movff recvd,recvdt
- =a swapfw ints
- movwf STATUS
- swapf intw
- swapfw intw
- retfie
- endlocal
-
- ; ----------------------------
- ; init PIC & mouse - continued
- ; ----------------------------
-
- start_a local
- movlf 0xff,0x1f
- if TOWER
- clrf PORTA
- clrf PORTB
- movlw b'11111111'
- tris PORTA
- tris PORTB
- else
- movlf b'00011111',PORTA
- movlf b'00011100',PORTB
- movlw b'00000000'
- tris PORTA
- movlw b'11100011'
- tris PORTB
- endif
- endlocal
-
- ; clear RAM
-
- movlf memstart,FSR
- sublw mem_end
- clearam clrf INDF
- incf FSR
- addlw 0xff
- bnz clearam
- movlf TRISB+0x80,FSR
-
- ; init variables
-
- movlf 24,wdtm
- movlf 11,recvc
-
- ; delay before turn mouse on
-
- callw delayms,0
- if TOWER ;turn on mouse
- movlw b'00001111'
- tris PORTA
- else
- bcf PORTA,4
- endif
- callw delayms,100
- movlw b'00000001' ;enable pull-up
- option
-
- ; wait for mouse
-
- local
- callw delayms,0
- callw delayms,0
- callw delayms,0
- callw delayms,0
- callw delayms,0
- callw delayms,0
- callw delayms,0
- callw delayms,0
- callw delayms,0
- callw delayms,0
- bcf INDF,0 ;inhibit I/O
- bsf INDF,1
- callw delayms,50
- if WHEEL
- callw send,0xf3 ;try to switch to wheel mode
- callw send,200
- callw send,0xf3
- callw send,100
- callw send,0xf3
- callw send,80
- callw send,0xF2 ;read mouse ID
- call bwait
- sublw 3 ;intellimouse compatible?
- skipnz
- bsf flags,fwheel ;yes
- endif
- callw send,0xe8 ;set resolution
- callw send,3 ;8/mm
- callw send,0xe6 ;scaling 1:1
- callw send,0xf3 ;set 200fps
- callw send,200
- callw send,0xf4 ;enable mouse in streaming mode
- if TOWER
- call cpoff
- else
- movlf 3,xtemp
- movwf ytemp
- movlf 2,xcount
- movwf ycount
- if WHEEL
- movwf zcount
- endif
- endif
- endlocal
-
- ; -----------
- ; check mouse
- ; -----------
-
- m_check callw send,0xE9
- bc start ;no response? init mouse again
- sublw 0xFA ;ACK?
- bnz start ;no ACK - init mouse again...
- call bwait ;receive status byte
- bc start
- andlw b'01100000' ;leave only stream & enable flags
- sublw b'00100000' ;must be stream and enabled
- bnz start
- btfsc flags,fnores
- goto p_init
- call bwait ;receive resolution (value ignored)
- bc nores ;no resolution...
- btfsc flags,fnofps
- goto p_init
- call bwait ;receive reports per second
- bc nofps ;no fps
- goto p_init
-
- ; no resolution & fps report
-
- nores bsf flags,fnores
- nofps bsf flags,fnofps
-
- ; ---------------------
- ; sync serial port init
- ; ---------------------
-
- p_init local
- movlf 3,recvb
- if WHEEL
- btfsc flags,fwheel
- incf recvb
- endif
- clrf currbyte
- if TOWER
- movfw INDF
- xorfw PORTB
- andlw b'00000100'
- bz =a
- bcf flags,fon ;mouse off
- movlw b'00001111' ;XxYy off
- tris PORTA
- movlw b'11111111' ;buttons and wheel off
- movwf INDF
- endif
- =a bsf INTCON,7 ;global interrupt enable
- bsf INTCON,4 ;enable RB0 interrupt
- endlocal
-
- ; check shift flag - byte received
-
- schk btfss flags,fbyte
- goto pchk1
- bcf flags,fbyte
- movfw currbyte
- addlw byte1
- movwf FSR
- movff recvdt,INDF
- movlf PORTB+0x80,FSR
- incf currbyte
- loop tchk,recvb
- movlf 3,recvb
- if WHEEL
- btfsc flags,fwheel
- incf recvb
- endif
- clrf currbyte
- bsf flags,fpkt1
- movlf 24,wdtm
- goto tchk
-
- ; check packet flag - packet received
-
- pchk1 btfss flags,fpkt1
- goto pchk2
- bcf flags,fpkt1
- bsf flags,fpkt2
- clrf xdir
- movlw 1
- btfsc byte1,4
- movlw 255
- movf byte2
- btfss STATUS,Z
- movwf xdir
- movfw byte2
- btfsc byte1,4
- sublw 0
- addfw xdif
- btfsc STATUS,C
- movlw 255
- movwf xdif
- movwf xspeed
- addwf xspeed
- skipc
- addwf xspeed
- skipc
- goto tchk
- movlf 255,xspeed
- goto tchk
-
- pchk2 btfss flags,fpkt2
- goto pchk3
- bcf flags,fpkt2
- bsf flags,fpkt3
- clrf ydir
- movlw 1
- btfsc byte1,5
- movlw 255
- movf byte3
- btfss STATUS,Z
- movwf ydir
- movfw byte3
- btfsc byte1,5
- sublw 0
- addfw ydif
- btfsc STATUS,C
- movlw 255
- movwf ydif
- movwf yspeed
- addwf yspeed
- skipc
- addwf yspeed
- skipc
- goto tchk
- movlf 255,yspeed
- goto tchk
-
- pchk3 btfss flags,fpkt3
- goto tchk
- bcf flags,fpkt3
- rlfw byte1
- movwf temp1
- rlf temp1
- comfw temp1
- andlw b'00011100'
- local
- if TOWER
- movwf temp1
- sublw b'00011100'
- skipz
- call cpoff
- btfss flags,fon
- goto =a
- if WHEEL
- movfw INDF
- andlw b'11100011'
- iorfw temp1
- else
- movfw temp1
- iorlw b'11100011'
- endif
- movwf INDF
- else
- movwf PORTB
- endif
- =a endlocal
- if WHEEL
- movfw byte4
- btfsc flags,fwheel
- addwf zdif
- endif
-
- ; check time to move
-
- tchk btfss RTCC,7
- goto schk
- sublf SPEED,RTCC
-
- ; CPU watchdog
-
- clrwdt
-
- ; check mouse
-
- mchk loop xchk,wdtm+1
- loop xchk,wdtm
- movlf 24,wdtm
- bcf INTCON,4 ;disable RB0 interrupt
- movfw recvb
- if WHEEL
- btfsc flags,fwheel
- addlw 255
- endif
- sublw 3 ;packet receive started?
- btfss STATUS,Z
- goto mchk_e ;yes
- movfw recvc
- sublw 11 ;byte receive started?
- btfss STATUS,Z
- goto mchk_e ;yes
- btfsc PORTB,0 ;bit receive started?
- goto m_check ;no
- mchk_e bsf INTCON,4 ;enable RB0 interrupt
-
- ; check X movement
-
- xchk movfw xspeed
- addwf xspeed+1
- btfss STATUS,C
- goto ychk
- movf xdif
- btfsc STATUS,Z
- goto ychk
- decf xdif
- movfw xdir
- subwf xcount
- rrfw xcount
- andlw 1
- xorfw xcount
- andlw 3
- movwf xtemp
-
- ; check Y movement
-
- ychk movfw yspeed
- addwf yspeed+1
- btfss STATUS,C
- goto zchk
- movf ydif
- btfsc STATUS,Z
- goto zchk
- decf ydif
- movfw ydir
- addwf ycount
- rrfw ycount
- andlw 1
- xorfw ycount
- andlw 3
- movwf ytemp
-
- ; check wheel movement
-
- zchk local
- if WHEEL
- btfsc PORTB,5
- goto =a
- ; if BUTT4
- ; btfss INDF,5
- ; goto =a
- ; endif
- movlf 2,zcount
- bsf INDF,6
- bsf INDF,7
- clrf zdif
- =a movf zdif
- bz xyout
- movlw 1
- btfss zdif,7
- sublw 0
- addwf zdif
- addwf zcount
- rrfw zcount
- andlw 1
- xorfw zcount
- movwf temp1
- movfw INDF
- andlw b'00111111'
- btfsc temp1,0
- iorlw b'01000000'
- btfsc temp1,1
- iorlw b'10000000'
- if TOWER
- btfsc flags,fon
- endif
- movwf INDF
- endif
- endlocal
-
- ; XY movement out
-
- xyout bcf STATUS,C
- rlfw xtemp
- addfw xtemp
- addfw xtemp
- iorfw ytemp
- if TOWER
- btfsc flags,fon
- tris PORTA
- else
- movwf PORTA
- endif
-
- ; packet bit shift watchdog
-
- wchk local
- loop schk,wdtp
- bcf INTCON,4 ;disable RB0 interrupt
- movf wdtp
- btfss STATUS,Z
- goto =a
- movlf 11,recvc
- bsf wdtp,5
- goto p_init
- =a bsf INTCON,4 ;enable RB0 interrupt
- goto schk
- endlocal
-
- ; check power off for tower version
-
- if TOWER
- cpoff btfsc flags,fon
- return
- comfw PORTA
- andlw b'00001111'
- btfsc STATUS,Z
- btfss PORTB,2
- return
- bsf flags,fon
- movlf 3,xtemp
- movwf ytemp
- movlf 2,xcount
- movwf ycount
- if WHEEL
- movwf zcount
- endif
- return
- endif
-
- ; ------------------
- ; send byte to mouse
- ; ------------------
-
- send local
- clrf INTCON
- movwf temp1
- movwf sendata
- clrf sendetc
- comf sendetc
- bcf INDF,0 ;inhibit I/O
- callw delayus,100
- movlf 8,count
- movlw 1
- =a rrf temp1 ;calculate parity
- skipnc
- xorwf sendetc
- loop =a,count
- movlf 11,count
- bsf INDF,0
- bcf INDF,1 ;initiate send
- =b clrwdt
- clrw
- =c addlw 1
- bz start ;timeout? reset mouse
- btfsc PORTB,0 ;wait for 0
- goto =c
- rrf sendetc
- rrf sendata
- btfss STATUS,C
- bcf INDF,1
- btfsc STATUS,C
- bsf INDF,1
- clrw
- =d addlw 1
- btfsc STATUS,Z ;timeout?
- goto start ;reset mouse
- btfss PORTB,0 ;wait for 1
- goto =d
- loop =b,count
- clrf INTCON
- endlocal
- ; to be continued
-
- ; -----------------------
- ; receive byte from mouse
- ; -----------------------
-
- bwait local
- bsf INTCON,7 ;global interrupt enable
- bsf INTCON,4 ;enable RB0 interrupt
- movlf 40,count
- =a clrwdt
- callw delayus,100
- btfss flags,fbyte
- goto =b
- bcf flags,fbyte
- movfw recvdt
- bcf STATUS,C
- return
- =b loop =a,count
- setc
- return
- endlocal
-
- ; ------
- ; delays
- ; ------
-
- delayms local
- movwf count
- =a clrwdt
- movlw 249
- =b addlw 0xff
- bnz =b
- loop =a,count
- return
- endlocal
-
- delayus addlw 0xff
- bnz delayus
- return
-
- end
-